﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace BaseThing.Engine
{
    class Emitter
    {

        public List<Particle> particles = new List<Particle>();
        public Texture2D texture;

        private double time;
        private double lastTime;

        //Attributes
        //=================================
        public float emissionRate;
        public float emissionRadius;

        public float life;
        public float lifeRange;

        public float size;
        public float sizeRange;

        public float saturation;
        public float alpha;

        public float spread;

        public float gravity;

        public float speed;

        public Vector2 position = Vector2.Zero;
        public Vector2 wind = Vector2.Zero;
        public Vector2 rotation = Vector2.Zero;

        private Random rnd = new Random();

        public Emitter()
        {
            time = 0;
            lastTime = -1;
            texture = null;

            emissionRate = 30.0f;
            emissionRadius = 0.0f;

            life = 2.0f;
            lifeRange = 0.5f;

            size = 5.0f;
            sizeRange = 2.0f;

            saturation = 1.0f;
            alpha = 0.5f;

            spread = 1.0f;

            speed = 1.0f;
            gravity = 0.0f;
        }

        public void Update(GameTime gameTime)
        {

            time += gameTime.ElapsedGameTime.TotalMilliseconds;

            if (texture == null)
                return;

            if (lastTime == -1)
                lastTime = time;

            int numEmission = (int)((double)(time - lastTime) / 1000.0f * emissionRate);


            for (int i = 0; i < numEmission; i++)
            {
                AddParticle();
            }

           
            if (numEmission > 0)
                lastTime = time;

  
            foreach (Particle particle in particles)
            {

                if (particle.active == false) continue;
                
                particle.acceleration.Y = -gravity;
                particle.acceleration = particle.acceleration + wind ;
                particle.alpha = alpha;
                particle.rotation = rotation;
                particle.speed = speed;

                particle.Update(gameTime);
            }
        }


        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.Additive);

            foreach (Particle particle in particles)
            {
                particle.Draw(spriteBatch);
            }

            spriteBatch.End();       
        }

        public void Draw(SpriteBatch spriteBatch, ref Camera2D cam, ref GraphicsDeviceManager graphics)
        {
            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.Additive, null, null, null, null, cam.GetMatrix(graphics.GraphicsDevice));
           
            foreach (Particle particle in particles)
            {
                particle.Draw(spriteBatch);
            }

            spriteBatch.End();
        }
        
        public void SetTexture(Texture2D tex)
        {
            texture = tex;
        }

        protected void AddParticle()
        {
            Particle particle = new Particle(particles.Count,texture);

            float r = frand(0.0f, 1.0f) * saturation + (1 - saturation);
            float g = frand(0.0f, 1.0f) * saturation + (1 - saturation);
            float b = frand(0.0f, 1.0f) * saturation + (1 - saturation);

            particle.color = new Color(r, g, b);
            particle.life = frand(life - lifeRange, life + lifeRange);
            particle.totalLife = particle.life;

            particle.speed = speed;

            particle.velocity = new Vector2(frand(-spread, spread), frand(-spread, spread)); //frand(3,20)

            particle.acceleration = new Vector2(0.0f, -gravity);
            particle.size = frand(size - sizeRange, size + sizeRange);

            particle.position.X = position.X + frand(-emissionRadius, emissionRadius);
            particle.position.Y = position.Y + frand(-emissionRadius, emissionRadius);

            particles.Add(particle);
        }

        protected float frand(float start, float end)
        {
            float num = (float)rnd.NextDouble();

            return (start + (end - start) * num);
        }


        public void RemoveInactive()
        {
            for (int i = particles.Count - 1; i >= 0; i-- )
            {
                Particle particle = particles[i];

                if (particle.active == false)
                {
                    particles.Remove(particle);
                }
            }
         
        }
    }
}
